﻿using System.Drawing;
using CAION2.Properties;

namespace CAION2.Classes
{
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Windows.Forms;
    using System.Windows.Media;

    using Models;
    using ViewModels;

    public class ItemSet
    {
        public class ItemInfo
        {
            public string Name;

            public string Translate;

            public bool InSet;
        }
        
        public DataRow Row { get; private set; }
        public List<ItemInfo> ItemsList { get; private set; }
        private byte FullSetPeacesCount { get; set; }

        private byte currentPeacesCount;
        public byte CurrentPeacesCount
        {
            get
            {
                return currentPeacesCount;
            }
            private set
            {
                if (Equals(value, currentPeacesCount)) return;
                currentPeacesCount = value;

                FillStatsList();
            }
        }
        public List<KeyValuePair<string, float>> StatsList { get; private set; } 


        private List<ItemInfo> FillItemsList(string[] firstItemInfo)
        {
            string conditionName = "name IN (";
            for (int i = 1; i <= 13; i++)
            {
                if (string.IsNullOrEmpty(Row["Item" + i].ToString())) continue;
                conditionName += string.Format("'{0}', ", Row["Item" + i]);
            }
            conditionName = conditionName.Remove(conditionName.Length - 2, 2) + ")";

            string selectCommand = DataModel.TableList.Aggregate("", (current, tableName) => current + string.Format("SELECT name, translate{0} AS translate FROM {1} WHERE {2} \nUNION ALL\n", DataModel.EngFix, tableName, conditionName));
            selectCommand = selectCommand.Remove(selectCommand.Length - 12);

            DataTable table = DataModel.GetTable(selectCommand);
            List<ItemInfo> result = new List<ItemInfo>();

            foreach (DataRow row in table.Rows)
            {
                ItemInfo info = new ItemInfo { Name = row["name"].ToString(), Translate = row["translate"].ToString() };
                info.InSet = info.Name == firstItemInfo[0];
                result.Add(info);
            }

            return result;
        }
        
        public static ItemSet GetItemSet(string[] itemInfo)
        {
            string condition =
                string.Format(
                    "'{0}' IN ([item1], [item2], [item3], [item4], [item5], [item6], [item7], [item8], [item9], [item10], [item11], [item12], [item13])",
                    itemInfo[0]);

            DataRow itemSetRow = DataModel.GetRow("ItemSets", condition);
            return string.IsNullOrEmpty(itemSetRow["name"].ToString()) ? null : new ItemSet(itemSetRow, itemInfo);
        }

        public ItemSet(DataRow row, string[] itemInfo)
        {
            Row = row;
            CurrentPeacesCount = 1;
            FullSetPeacesCount = (byte)Row.ItemArray.Skip(3).Take(13).Count(f => f.ToString() != "");
            ItemsList = FillItemsList(itemInfo);
        }

        public void AddItemInSet(string itemName)
        {
            ItemInfo itemInfo = ItemsList.Find(i => i.Name == itemName);
            itemInfo.InSet = true;
            CurrentPeacesCount = (byte)ItemsList.Count(i => i.InSet);
        }

        public void DelItemInSet(string itemName)
        {
            ItemInfo itemInfo = ItemsList.Find(i => i.Name == itemName);
            itemInfo.InSet = false;
            CurrentPeacesCount = (byte)ItemsList.Count(i => i.InSet);
        }

        public string GetTranslate()
        {
            return string.Format(
                "{0} ({1}/{2})",
                Row["translate" + DataModel.EngFix],
                CurrentPeacesCount,
                FullSetPeacesCount);
        }

        public string GetCharacters(SolidColorBrush textColor)
        {
            System.Drawing.Color color = ColorTranslator.FromHtml(textColor.ToString());
            color = ControlPaint.Dark(color, 0.03f);
            string captionColor = ColorTranslator.ToHtml(color);
            
            string result = string.Format("[color={0}]{1}[/color]\n", captionColor, GetTranslate());
            
            foreach (ItemInfo info in ItemsList)
            {
                if (info.InSet)
                {
                    result += string.Format("[color={0}]{1}[/color]\n", textColor, info.Translate);
                }
                else
                {
                    result += string.Format("{0}\n", info.Translate);
                }
            }

            result += "\n";
            string pieceBonus;
            ItemSetTextConverter converter = new ItemSetTextConverter();

            for (int i = 2; i <= 6; i++)
            {
                pieceBonus = Row["piece_bonus" + i].ToString();
                if (string.IsNullOrEmpty(pieceBonus)) continue;

                result += string.Format(Resources.ItemSet_EquipmentEffect, i, captionColor) + "\n";
                
                int x = 0;
                string caret = "\t  ";

                string[] stats = pieceBonus.Split(';');
                foreach (KeyValuePair<string, float> statPair in stats.Select(CardStat.GetStat))
                {
                    if (CurrentPeacesCount >= i)
                    {
                        result += string.Format("[color={0}]{1}[/color]", textColor, converter.Convert(statPair, null, true, null)) + caret;
                    }
                    else
                    {
                        result += converter.Convert(statPair, null, false, null) + caret;
                    }

                    caret = x % 2 == 0 ? "\n" : "\t  ";
                    x++;
                }
                result += "\n";
            }

            pieceBonus = Row["fullset_bonus"].ToString();
            if (!string.IsNullOrEmpty(pieceBonus))
            {
                result += string.Format(Resources.ItemSet_FullSetEffect, captionColor) + "\n";
                
                int x = 0;
                string caret = "\t  ";

                string[] stats = pieceBonus.Split(';');
                foreach (KeyValuePair<string, float> statPair in stats.Select(CardStat.GetStat))
                {
                    if (CurrentPeacesCount == FullSetPeacesCount)
                    {
                        result += string.Format("[color={0}]{1}[/color]", textColor, converter.Convert(statPair, null, true, null)) + caret;
                    }
                    else
                    {
                        result += converter.Convert(statPair, null, false, null) + caret;
                    }

                    caret = x % 2 == 0 ? "\n" : "\t  ";
                    x++;
                }
            }

            return result;
        }

        private void FillStatsList()
        {
            StatsList = new List<KeyValuePair<string, float>>();
            if (CurrentPeacesCount < 2) return;

            string pieceBonus;

            for (int i = 2; i <= currentPeacesCount; i++)
            {
                pieceBonus = Row["piece_bonus" + i].ToString();
                if (string.IsNullOrEmpty(pieceBonus)) continue;

                string[] stats = pieceBonus.Split(';');
                foreach (KeyValuePair<string, float> statPair in stats.Select(CardStat.GetStat))
                {
                    StatsList.Add(statPair);
                }
            }

            if (CurrentPeacesCount < FullSetPeacesCount) return;

            pieceBonus = Row["fullset_bonus"].ToString();
            if (!string.IsNullOrEmpty(pieceBonus))
            {
                string[] stats = pieceBonus.Split(';');
                foreach (KeyValuePair<string, float> statPair in stats.Select(CardStat.GetStat))
                {
                    StatsList.Add(statPair);
                }
            }
        }
    }

    public class ItemSets
    {
        public List<ItemSet> ItemsSetList { get; set; }
        
        public ItemSets()
        {
            ItemsSetList = new List<ItemSet>();
        }

        public void AddItemSet(string[] itemInfo)
        {
            string condition =
                string.Format(
                    "'{0}' IN ([item1], [item2], [item3], [item4], [item5], [item6], [item7], [item8], [item9], [item10], [item11], [item12], [item13])",
                    itemInfo[0]);

            DataRow itemSetRow = DataModel.GetRow("ItemSets", condition);
            if (string.IsNullOrEmpty(itemSetRow["name"].ToString())) return;

            ItemSet set = ItemsSetList.Find(s => s.Row["name"].ToString() == itemSetRow["name"].ToString());

            if (set == null)
            {
                ItemsSetList.Add(new ItemSet(itemSetRow, itemInfo));
            }
            else
            {
                set.AddItemInSet(itemInfo[0]);
            }

        }

        public void DelItemSet(string itemName)
        {
            ItemSet set = GetItemSet(itemName);

            if (set == null)
            {
                return;
            }

            set.DelItemInSet(itemName);
            if (set.CurrentPeacesCount == 0) ItemsSetList.Remove(set);
        }
        
        public ItemSet GetItemSet(string itemName)
        {
            return ItemsSetList.Find(s => s.ItemsList.Exists(i => i.Name == itemName));
        }
        
    }
}
